from textual.app import App, ComposeResult

from textual.widgets import ListView, ListItem, Label, Header, Footer, TextArea, Input
from textual.command import Provider, Hit, Hits

from textual.containers import Vertical, Horizontal

from textual.binding import Binding

from typing import List
from functools import partial

class WantItem(ListItem):

    def __init__(self, want, view_text=None):
        if view_text is None:
            view_text = want
        super().__init__(Label(view_text))
        self.want = want

class YwloaderProvider(Provider):
    '''数据提供器'''

    async def startup(self) -> None:
        app:YwloaderApp = self.app
        worker = self.app.run_worker(app.load_files, thread=True)
        self.files = await worker.wait()
        self.app.notify(f'{len(self.files)} 项')
    
    async def search(self, query: str) -> Hits:
        matcher = self.matcher(query)

        app:YwloaderApp = self.app

        assert isinstance(app, YwloaderApp)

        for file in self.files:
            command = f'open: {file}'
            score = matcher.match(command)
            if score > 0:
                yield Hit(
                    score,
                    matcher.highlight(command),
                    partial(app.view_want_file, file),
                    help=f'Show content "{file}"'
                )

class YwloaderApp(App):

    CSS_PATH = 'ywloader_app.tcss'

    BINDINGS = [
        Binding('/', 'app.command_palette()', '准备显示')
    ]

    COMMANDS = {YwloaderProvider}

    def compose(self) -> ComposeResult:
        yield Header()
        with Horizontal():
            with Vertical(classes='leftview'):
                yield Input(placeholder='请输入关键词...')
                yield ListView()
            yield TextArea()
        yield Footer()

    def on_mount(self) -> None:
        self.listview = self.query_one(ListView)
        self.listview.border_title = "想法列表"
        self.textarea = self.query_one(TextArea)
        self.textarea.border_title = "想法内容"
        self.input = self.query_one(Input)
        self.input.border_title = "过滤想法"
        self.searching = False

        # for want in self.load_wants():
        #     self.listview.append(WantItem(want))

        self.on_input_changed(Input.Changed(None, ''))
            
    def on_list_view_highlighted(self, event: ListView.Highlighted):
        item: WantItem = event.item
        if isinstance(item, WantItem):
            self.show_want(item.want)

    def on_input_changed(self, event: Input.Changed):
        self.listview.clear()
        for want in self.load_wants():
            if event.value in want:
                self.listview.append(WantItem(want, f'{len(self.listview._nodes)+1}. {want}'))
        
    def show_want(self, want):
        import subprocess
        output = subprocess.check_output(f"ywloader-cli show '{want}'", shell=True,stderr=subprocess.PIPE).decode('utf-8')
        self.query_one(TextArea).load_text(output)

    def load_wants(self) -> List:
        # ywloader-cli search --all --json
        import subprocess
        output = subprocess.check_output('ywloader-cli search --all --json', shell=True, stderr=subprocess.PIPE).decode('utf-8')

        import json
        return list(json.loads(output))

    def load_files(self) -> List:
        import subprocess
        if not self.listview.highlighted_child:
            return []
        
        item: WantItem = self.listview.highlighted_child
        output = subprocess.check_output(f"ywloader-cli list --files '{item.want}'", shell=True, stderr=subprocess.PIPE).decode('utf-8')
        return output.splitlines()
    

    def view_want_file(self, file):
        ''''''
        import subprocess
        item: WantItem = self.listview.highlighted_child
        output = subprocess.check_output(f"ywloader-cli cat '{item.want}' '{file}'", shell=True,stderr=subprocess.PIPE).decode('utf-8')
        self.textarea.load_text(output)

YwloaderApp().run()